<template>
  <div class="left-panel">
    <div class="image-wrapper">
      <img
        :src="currentDeviceImage"
        alt="Device Diagram"
        class="device-image"
        @load="positionSensorDots"
      />
    </div>

    <div class="sensor-dots-container" ref="sensorDotsContainer"></div>

    <SensorChartPopup
      v-for="point in sensorPoints"
      :key="point.id"
      :id="`chartPopup${point.id}`"
      :sensor-id="point.id"
      @close-popup="closePopup(`chartPopup${point.id}`)"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import SensorChartPopup from './SensorChartPopup.vue' // Ensure this path is correct

const props = defineProps({
  currentDevice: String,
  sensorPoints: Array, // Expected format: [{ id: '1', left: '25', top: '50', data: {...} }, ...]
})

// Computed property to get the correct image path based on currentDevice prop.
const currentDeviceImage = computed(() => {
  const imageName = props.currentDevice === '联醇装置' ? 'device.png' : 'device1.png'
  // Use a direct path for static assets, assuming they are in the public/img folder
  // or built by your bundler into an accessible path.
  return `/img/${imageName}`
})

// Vue ref to the container where sensor dots will be dynamically appended.
const sensorDotsContainer = ref(null)

// Closes a specific chart popup.
const closePopup = (popupId) => {
  const popup = document.getElementById(popupId)
  if (popup) {
    popup.style.display = 'none'
  }
}

// Function to position the sensor dots dynamically over the image.
const positionSensorDots = async () => {
  // Ensure the image and its natural dimensions are available after DOM updates.
  await nextTick() // Wait for the image to potentially re-render or update its dimensions.

  const deviceImage = document.querySelector('.left-panel .device-image')

  // Check if the image and sensorDotsContainer ref are available and have valid dimensions.
  if (
    !deviceImage ||
    deviceImage.offsetWidth === 0 ||
    deviceImage.offsetHeight === 0 ||
    !sensorDotsContainer.value
  ) {
    console.warn('Image or sensorDotsContainer not ready, retrying positionSensorDots...')
    // If not ready, re-attempt after a short delay or nextTick, but be careful of infinite loops.
    // For now, rely on @load event and watch to re-trigger.
    return
  }

  // Get dimensions and positions relative to the .left-panel parent.
  // Using offsetLeft/offsetTop/offsetWidth/offsetHeight for elements within a positioned parent
  // can be simpler if the parent's padding/border is accounted for.
  // Using getBoundingClientRect() is more robust for general cases.
  const imageRect = deviceImage.getBoundingClientRect()
  const leftPanelRect = deviceImage.closest('.left-panel').getBoundingClientRect()

  const imgActualLeftInPanel = imageRect.left - leftPanelRect.left
  const imgActualTopInPanel = imageRect.top - leftPanelRect.top
  const imgActualWidth = imageRect.width
  const imgActualHeight = imageRect.height

  // Position the sensorDotsContainer precisely over the image.
  // It takes the exact dimensions and position of the image within the left-panel.
  sensorDotsContainer.value.style.position = 'absolute'
  sensorDotsContainer.value.style.left = `${imgActualLeftInPanel}px`
  sensorDotsContainer.value.style.top = `${imgActualTopInPanel}px`
  sensorDotsContainer.value.style.width = `${imgActualWidth}px`
  sensorDotsContainer.value.style.height = `${imgActualHeight}px`
  sensorDotsContainer.value.innerHTML = '' // Clear existing sensor dots before redrawing.

  // Create and append each sensor dot.
  props.sensorPoints.forEach((point) => {
    const dot = document.createElement('div')
    dot.className = 'sensor-dot' // Apply CSS class for styling.
    dot.id = `dot${point.id}` // Assign a unique ID.
    dot.setAttribute('data-dot-id', point.id) // Custom attribute for easy lookup.

    // Calculate pixel position based on percentage and actual image dimensions.
    // Ensure point.left and point.top are treated as numbers.
    const dotPixelLeft = (parseFloat(point.left) / 100) * imgActualWidth
    const dotPixelTop = (parseFloat(point.top) / 100) * imgActualHeight

    dot.style.top = `${dotPixelTop}px`
    dot.style.left = `${dotPixelLeft}px`

    // Add click event listener to open/position the chart popup.
    dot.addEventListener('click', (event) => handleSensorDotClick(point.id, dot, event))
    sensorDotsContainer.value.appendChild(dot)
  })
}

// Function to handle sensor dot clicks and position popups.
const handleSensorDotClick = (dotId, dotElement, event) => {
  event.stopPropagation() // Prevent the click from propagating to parent elements.

  // Close all other open popups.
  document.querySelectorAll('.chart-popup').forEach((popup) => {
    if (popup.style.display === 'flex' && popup.id !== `chartPopup${dotId}`) {
      popup.style.display = 'none'
    }
  })

  const targetPopup = document.getElementById(`chartPopup${dotId}`)
  if (!targetPopup) {
    console.warn(`Chart popup with ID chartPopup${dotId} not found.`)
    return
  }

  // Toggle display for the target popup.
  if (targetPopup.style.display === 'flex') {
    targetPopup.style.display = 'none'
    return // If it was open and we just closed it, stop here.
  }

  // Get necessary dimensions for positioning the popup.
  const deviceImage = document.querySelector('.left-panel .device-image')
  const leftPanel = deviceImage.closest('.left-panel')
  const imageRect = deviceImage.getBoundingClientRect()
  const leftPanelRect = leftPanel.getBoundingClientRect()

  // Calculate image position relative to the left-panel.
  const imgActualLeftInPanel = imageRect.left - leftPanelRect.left
  const imgActualTopInPanel = imageRect.top - leftPanelRect.top
  const imgActualWidth = imageRect.width
  const imgActualHeight = imageRect.height

  // Dot's position relative to the image (since sensor-dots-container is over the image).
  const dotPixelLeftInImage = parseFloat(dotElement.style.left)
  const dotPixelTopInImage = parseFloat(dotElement.style.top)

  // Calculate desired popup position (centered on dot, then adjusted).
  // Initial position relative to the left-panel's top-left corner.
  let topPos = imgActualTopInPanel + dotPixelTopInImage - targetPopup.offsetHeight / 2
  let leftPos = imgActualLeftInPanel + dotPixelLeftInImage - targetPopup.offsetWidth / 2
  const imagePadding = 10 // Padding to keep popup slightly away from image edges.

  // Adjust popup position to keep it within the bounds of the image (or the area occupied by the image).
  // The popup should ideally stay within the visible area of the image in the left-panel.
  const maxLeft = imgActualLeftInPanel + imgActualWidth - targetPopup.offsetWidth - imagePadding
  const maxTop = imgActualTopInPanel + imgActualHeight - targetPopup.offsetHeight - imagePadding

  if (leftPos < imgActualLeftInPanel + imagePadding) {
    leftPos = imgActualLeftInPanel + imagePadding
  } else if (leftPos > maxLeft) {
    leftPos = maxLeft
  }

  if (topPos < imgActualTopInPanel + imagePadding) {
    topPos = imgActualTopInPanel + imagePadding
  } else if (topPos > maxTop) {
    topPos = maxTop
  }

  // Apply calculated position and make popup visible.
  targetPopup.style.top = `${topPos}px`
  targetPopup.style.left = `${leftPos}px`
  targetPopup.style.display = 'flex' // Show the popup.
}

// Watch for changes in currentDevice prop to re-position dots.
watch(
  () => props.currentDevice,
  async () => {
    // Use nextTick to ensure DOM updates (like image src change) are applied
    // before trying to measure and position elements.
    await nextTick()
    positionSensorDots()
  },
)

// Watch for changes in sensorPoints prop (if the points themselves can change for a device).
watch(
  () => props.sensorPoints,
  async () => {
    await nextTick()
    positionSensorDots()
  },
  { deep: true }, // Use deep: true if individual point properties might change.
)

let resizeObserver = null // Use ResizeObserver for better responsiveness.

onMounted(() => {
  // Initial positioning when the component mounts.
  positionSensorDots()

  // Use ResizeObserver to react to dimension changes of the .left-panel or .device-image.
  // This is much more efficient than listening to window resize for responsiveness.
  const targetElement = document.querySelector('.left-panel .device-image')
  if (targetElement) {
    resizeObserver = new ResizeObserver(() => {
      // Re-position dots when the image element's size changes.
      positionSensorDots()
    })
    resizeObserver.observe(targetElement)
  } else {
    console.warn('Target image for ResizeObserver not found.')
  }
})

// Clean up the ResizeObserver when the component is unmounted.
onUnmounted(() => {
  if (resizeObserver) {
    resizeObserver.disconnect()
  }
})
</script>

<style scoped>
/*
  Styles for .left-panel, .device-image, .sensor-dots-container, .sensor-dot,
  and .chart-popup should be defined here or imported.
*/

.left-panel {
  flex: 1.5;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  padding: 20px;
  display: block;
  overflow: hidden;
  position: relative; /* Crucial for absolute positioning of children like image-wrapper and sensor-dots-container */
}

/* New wrapper for fixed aspect ratio to prevent image reflow issues */
.image-wrapper {
  width: 100%;
  /* Assuming a 4:3 aspect ratio for the image. Adjust padding-bottom if your image ratio is different (e.g., 16:9 would be 56.25%).
     This creates a container that maintains its aspect ratio, and the image inside scales to fit. */
  padding-bottom: 75%; /* Example: For a 4:3 image aspect ratio (3/4 * 100%) */
  position: relative;
  overflow: hidden; /* Hide any overflow if object-fit: contain leaves gaps */
}

.device-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%; /* Force image width to fill image-wrapper */
  height: 100%; /* Force image height to fill image-wrapper */
  object-fit: contain; /* Preserve aspect ratio, scale to fit, possibly leaving empty space */
  /* If you want the image to fill the entire container and potentially be cropped, use object-fit: cover; */
  display: block;
  border-radius: 5px;
}

.sensor-dots-container {
  /* This container will be absolutely positioned over the image by JS */
  /* Do not set static top/left/width/height here, it's handled by positionSensorDots() */
  pointer-events: none; /* Allows click events to "fall through" this container to the dots within it */
}

.sensor-dot {
  width: 30px; /* Slightly smaller dots */
  height: 30px;
  background-color: #4caf50; /* Green color for the dot */
  border-radius: 50%;
  position: absolute; /* Positioned within .sensor-dots-container */
  transform: translate(
    -50%,
    -50%
  ); /* Centers the dot precisely on its calculated (top, left) coordinates */
  cursor: pointer;
  z-index: 10; /* Ensure dot is above the image */
  box-shadow:
    0 0 8px rgba(0, 255, 0, 0.9),
    0 0 15px rgba(0, 255, 0, 0.6); /* More prominent glow */
  pointer-events: all; /* Make the dot itself clickable, overriding container's pointer-events: none */
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 0.8em; /* Adjust font size if adding numbers/text to dots */
  /* Optional: Add a subtle animation */
  transition:
    transform 0.2s ease-in-out,
    background-color 0.2s ease-in-out;
}

.sensor-dot:hover {
  background-color: #66bb6a; /* Lighter green on hover */
  transform: translate(-50%, -50%) scale(1.1); /* Slightly enlarge on hover */
}

/* Styles for SensorChartPopup (assuming it's a separate component) */
/* These styles should ideally be in SensorChartPopup.vue's <style scoped> block */
/* For illustrative purposes, here are common styles for .chart-popup */
/*
.chart-popup {
  position: absolute;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  padding: 15px;
  z-index: 20; // Higher than sensor dots
  width: 400px; // Example width
  height: 250px; // Example height
  display: none; // Controlled by JS (flex when visible)
  flex-direction: column;
  justify-content: flex-start; // Align content from the start
  align-items: center;
  gap: 10px; // Space between items in the popup
}

.chart-popup .close-chart-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  background: none;
  border: none;
  font-size: 1.5em;
  cursor: pointer;
  color: #555;
  z-index: 21; // Higher than popup content
}
.chart-popup canvas {
  width: 100% !important;
  height: 100% !important;
}
*/
</style>
